Analysis and visualisation of spatial transcriptomics data. Generally followed this Seurat workflow.
Load libraries
library(Seurat)
library(ggplot2)
library(patchwork)
library(dplyr)
library(UCell)
#library(ggpubr)
Load merged liver slices and set identity
sobj <- readRDS("../spatial/merged_spatial_sobj.RDS")
Idents(sobj) <- "SCT_snn_res.0.2"
Visualise clusters on spatial plot
plot1 <- SpatialDimPlot(sobj, alpha = 0.7, images = 'slice1') & NoLegend()
plot2 <- SpatialDimPlot(sobj, alpha = 0.7, images = 'slice1.1') +
labs(fill = "Cluster")
plot1 + plot2
pdf("./figures/spatial/merged_dimPlot_UMAP.pdf")
plot1 + plot2
dev.off()
png
2
Visualise features on spatial plot
Look at other genes
gene <- "Saa2;Saa1-1"
plot1 <- SpatialFeaturePlot(sobj, features = gene, images = 'slice1') & NoLegend()
plot2 <- SpatialFeaturePlot(sobj, features = gene, images = 'slice1.1') & NoLegend()
print(plot1 + plot2)
Calculate markers
all.markers <- FindAllMarkers(sobj,
only.pos = TRUE,
min.pct = 0.25,
logfc.threshold = 0.25,
recorrect_umi = FALSE)
Calculating cluster 0
| | 0 % ~calculating
|+++ | 4 % ~00s
|+++++ | 9 % ~00s
|+++++++ | 13% ~00s
|+++++++++ | 17% ~00s
|+++++++++++ | 22% ~00s
|++++++++++++++ | 26% ~00s
|++++++++++++++++ | 30% ~00s
|++++++++++++++++++ | 35% ~00s
|++++++++++++++++++++ | 39% ~00s
|++++++++++++++++++++++ | 43% ~00s
|++++++++++++++++++++++++ | 48% ~00s
|+++++++++++++++++++++++++++ | 52% ~00s
|+++++++++++++++++++++++++++++ | 57% ~00s
|+++++++++++++++++++++++++++++++ | 61% ~00s
|+++++++++++++++++++++++++++++++++ | 65% ~00s
|+++++++++++++++++++++++++++++++++++ | 70% ~00s
|+++++++++++++++++++++++++++++++++++++ | 74% ~00s
|++++++++++++++++++++++++++++++++++++++++ | 78% ~00s
|++++++++++++++++++++++++++++++++++++++++++ | 83% ~00s
|++++++++++++++++++++++++++++++++++++++++++++ | 87% ~00s
|++++++++++++++++++++++++++++++++++++++++++++++ | 91% ~00s
|++++++++++++++++++++++++++++++++++++++++++++++++ | 96% ~00s
|++++++++++++++++++++++++++++++++++++++++++++++++++| 100% elapsed=00s
Calculating cluster 1
| | 0 % ~calculating
|+++ | 4 % ~00s
|+++++ | 8 % ~00s
|+++++++ | 12% ~00s
|+++++++++ | 17% ~00s
|+++++++++++ | 21% ~00s
|+++++++++++++ | 25% ~00s
|+++++++++++++++ | 29% ~00s
|+++++++++++++++++ | 33% ~00s
|+++++++++++++++++++ | 38% ~00s
|+++++++++++++++++++++ | 42% ~00s
|+++++++++++++++++++++++ | 46% ~00s
|+++++++++++++++++++++++++ | 50% ~00s
|++++++++++++++++++++++++++++ | 54% ~00s
|++++++++++++++++++++++++++++++ | 58% ~00s
|++++++++++++++++++++++++++++++++ | 62% ~00s
|++++++++++++++++++++++++++++++++++ | 67% ~00s
|++++++++++++++++++++++++++++++++++++ | 71% ~00s
|++++++++++++++++++++++++++++++++++++++ | 75% ~00s
|++++++++++++++++++++++++++++++++++++++++ | 79% ~00s
|++++++++++++++++++++++++++++++++++++++++++ | 83% ~00s
|++++++++++++++++++++++++++++++++++++++++++++ | 88% ~00s
|++++++++++++++++++++++++++++++++++++++++++++++ | 92% ~00s
|++++++++++++++++++++++++++++++++++++++++++++++++ | 96% ~00s
|++++++++++++++++++++++++++++++++++++++++++++++++++| 100% elapsed=00s
Calculating cluster 2
| | 0 % ~calculating
|++ | 3 % ~00s
|++++ | 6 % ~00s
|+++++ | 10% ~00s
|+++++++ | 13% ~00s
|+++++++++ | 16% ~00s
|++++++++++ | 19% ~00s
|++++++++++++ | 23% ~00s
|+++++++++++++ | 26% ~00s
|+++++++++++++++ | 29% ~00s
|+++++++++++++++++ | 32% ~00s
|++++++++++++++++++ | 35% ~00s
|++++++++++++++++++++ | 39% ~00s
|+++++++++++++++++++++ | 42% ~00s
|+++++++++++++++++++++++ | 45% ~00s
|+++++++++++++++++++++++++ | 48% ~00s
|++++++++++++++++++++++++++ | 52% ~00s
|++++++++++++++++++++++++++++ | 55% ~00s
|++++++++++++++++++++++++++++++ | 58% ~00s
|+++++++++++++++++++++++++++++++ | 61% ~00s
|+++++++++++++++++++++++++++++++++ | 65% ~00s
|++++++++++++++++++++++++++++++++++ | 68% ~00s
|++++++++++++++++++++++++++++++++++++ | 71% ~00s
|++++++++++++++++++++++++++++++++++++++ | 74% ~00s
|+++++++++++++++++++++++++++++++++++++++ | 77% ~00s
|+++++++++++++++++++++++++++++++++++++++++ | 81% ~00s
|++++++++++++++++++++++++++++++++++++++++++ | 84% ~00s
|++++++++++++++++++++++++++++++++++++++++++++ | 87% ~00s
|++++++++++++++++++++++++++++++++++++++++++++++ | 90% ~00s
|+++++++++++++++++++++++++++++++++++++++++++++++ | 94% ~00s
|+++++++++++++++++++++++++++++++++++++++++++++++++ | 97% ~00s
|++++++++++++++++++++++++++++++++++++++++++++++++++| 100% elapsed=00s
Calculating cluster 3
| | 0 % ~calculating
|+++ | 5 % ~00s
|+++++ | 9 % ~00s
|+++++++ | 14% ~00s
|++++++++++ | 18% ~00s
|++++++++++++ | 23% ~00s
|++++++++++++++ | 27% ~00s
|++++++++++++++++ | 32% ~00s
|+++++++++++++++++++ | 36% ~00s
|+++++++++++++++++++++ | 41% ~00s
|+++++++++++++++++++++++ | 45% ~00s
|+++++++++++++++++++++++++ | 50% ~00s
|++++++++++++++++++++++++++++ | 55% ~00s
|++++++++++++++++++++++++++++++ | 59% ~00s
|++++++++++++++++++++++++++++++++ | 64% ~00s
|+++++++++++++++++++++++++++++++++++ | 68% ~00s
|+++++++++++++++++++++++++++++++++++++ | 73% ~00s
|+++++++++++++++++++++++++++++++++++++++ | 77% ~00s
|+++++++++++++++++++++++++++++++++++++++++ | 82% ~00s
|++++++++++++++++++++++++++++++++++++++++++++ | 86% ~00s
|++++++++++++++++++++++++++++++++++++++++++++++ | 91% ~00s
|++++++++++++++++++++++++++++++++++++++++++++++++ | 95% ~00s
|++++++++++++++++++++++++++++++++++++++++++++++++++| 100% elapsed=00s
Calculating cluster 4
| | 0 % ~calculating
|+ | 1 % ~01s
|++ | 3 % ~01s
|+++ | 4 % ~01s
|+++ | 5 % ~01s
|++++ | 7 % ~01s
|+++++ | 8 % ~01s
|+++++ | 10% ~01s
|++++++ | 11% ~01s
|+++++++ | 12% ~01s
|+++++++ | 14% ~01s
|++++++++ | 15% ~01s
|+++++++++ | 16% ~01s
|+++++++++ | 18% ~01s
|++++++++++ | 19% ~00s
|+++++++++++ | 21% ~00s
|+++++++++++ | 22% ~00s
|++++++++++++ | 23% ~00s
|+++++++++++++ | 25% ~00s
|++++++++++++++ | 26% ~00s
|++++++++++++++ | 27% ~00s
|+++++++++++++++ | 29% ~00s
|++++++++++++++++ | 30% ~00s
|++++++++++++++++ | 32% ~00s
|+++++++++++++++++ | 33% ~00s
|++++++++++++++++++ | 34% ~00s
|++++++++++++++++++ | 36% ~00s
|+++++++++++++++++++ | 37% ~00s
|++++++++++++++++++++ | 38% ~00s
|++++++++++++++++++++ | 40% ~00s
|+++++++++++++++++++++ | 41% ~00s
|++++++++++++++++++++++ | 42% ~00s
|++++++++++++++++++++++ | 44% ~00s
|+++++++++++++++++++++++ | 45% ~00s
|++++++++++++++++++++++++ | 47% ~00s
|++++++++++++++++++++++++ | 48% ~00s
|+++++++++++++++++++++++++ | 49% ~00s
|++++++++++++++++++++++++++ | 51% ~00s
|+++++++++++++++++++++++++++ | 52% ~00s
|+++++++++++++++++++++++++++ | 53% ~00s
|++++++++++++++++++++++++++++ | 55% ~00s
|+++++++++++++++++++++++++++++ | 56% ~00s
|+++++++++++++++++++++++++++++ | 58% ~00s
|++++++++++++++++++++++++++++++ | 59% ~00s
|+++++++++++++++++++++++++++++++ | 60% ~00s
|+++++++++++++++++++++++++++++++ | 62% ~00s
|++++++++++++++++++++++++++++++++ | 63% ~00s
|+++++++++++++++++++++++++++++++++ | 64% ~00s
|+++++++++++++++++++++++++++++++++ | 66% ~00s
|++++++++++++++++++++++++++++++++++ | 67% ~00s
|+++++++++++++++++++++++++++++++++++ | 68% ~00s
|+++++++++++++++++++++++++++++++++++ | 70% ~00s
|++++++++++++++++++++++++++++++++++++ | 71% ~00s
|+++++++++++++++++++++++++++++++++++++ | 73% ~00s
|+++++++++++++++++++++++++++++++++++++ | 74% ~00s
|++++++++++++++++++++++++++++++++++++++ | 75% ~00s
|+++++++++++++++++++++++++++++++++++++++ | 77% ~00s
|++++++++++++++++++++++++++++++++++++++++ | 78% ~00s
|++++++++++++++++++++++++++++++++++++++++ | 79% ~00s
|+++++++++++++++++++++++++++++++++++++++++ | 81% ~00s
|++++++++++++++++++++++++++++++++++++++++++ | 82% ~00s
|++++++++++++++++++++++++++++++++++++++++++ | 84% ~00s
|+++++++++++++++++++++++++++++++++++++++++++ | 85% ~00s
|++++++++++++++++++++++++++++++++++++++++++++ | 86% ~00s
|++++++++++++++++++++++++++++++++++++++++++++ | 88% ~00s
|+++++++++++++++++++++++++++++++++++++++++++++ | 89% ~00s
|++++++++++++++++++++++++++++++++++++++++++++++ | 90% ~00s
|++++++++++++++++++++++++++++++++++++++++++++++ | 92% ~00s
|+++++++++++++++++++++++++++++++++++++++++++++++ | 93% ~00s
|++++++++++++++++++++++++++++++++++++++++++++++++ | 95% ~00s
|++++++++++++++++++++++++++++++++++++++++++++++++ | 96% ~00s
|+++++++++++++++++++++++++++++++++++++++++++++++++ | 97% ~00s
|++++++++++++++++++++++++++++++++++++++++++++++++++| 99% ~00s
|++++++++++++++++++++++++++++++++++++++++++++++++++| 100% elapsed=01s
top.markers <- all.markers %>% group_by(cluster) %>% top_n(n = 10, wt = avg_log2FC)
top.markers
Create zonation scores using top 10 genes from periportal and pericentral clusters
# Compare clusters 0 and 1
markers <- FindMarkers(sobj,
ident.1 = '0',
ident.2 = '1',
only.pos = FALSE,
min.pct = 0.25,
logfc.threshold = 0.25,
recorrect_umi = FALSE)
| | 0 % ~calculating
|+ | 1 % ~01s
|++ | 3 % ~01s
|++ | 4 % ~01s
|+++ | 5 % ~01s
|++++ | 6 % ~01s
|++++ | 8 % ~01s
|+++++ | 9 % ~01s
|++++++ | 10% ~01s
|++++++ | 11% ~01s
|+++++++ | 13% ~01s
|+++++++ | 14% ~01s
|++++++++ | 15% ~01s
|+++++++++ | 16% ~01s
|+++++++++ | 18% ~01s
|++++++++++ | 19% ~01s
|+++++++++++ | 20% ~01s
|+++++++++++ | 22% ~01s
|++++++++++++ | 23% ~01s
|+++++++++++++ | 24% ~01s
|+++++++++++++ | 25% ~01s
|++++++++++++++ | 27% ~01s
|++++++++++++++ | 28% ~01s
|+++++++++++++++ | 29% ~01s
|++++++++++++++++ | 30% ~01s
|++++++++++++++++ | 32% ~01s
|+++++++++++++++++ | 33% ~01s
|++++++++++++++++++ | 34% ~01s
|++++++++++++++++++ | 35% ~01s
|+++++++++++++++++++ | 37% ~01s
|+++++++++++++++++++ | 38% ~01s
|++++++++++++++++++++ | 39% ~01s
|+++++++++++++++++++++ | 41% ~01s
|+++++++++++++++++++++ | 42% ~01s
|++++++++++++++++++++++ | 43% ~01s
|+++++++++++++++++++++++ | 44% ~01s
|+++++++++++++++++++++++ | 46% ~01s
|++++++++++++++++++++++++ | 47% ~01s
|+++++++++++++++++++++++++ | 48% ~01s
|+++++++++++++++++++++++++ | 49% ~01s
|++++++++++++++++++++++++++ | 51% ~01s
|++++++++++++++++++++++++++ | 52% ~01s
|+++++++++++++++++++++++++++ | 53% ~01s
|++++++++++++++++++++++++++++ | 54% ~01s
|++++++++++++++++++++++++++++ | 56% ~01s
|+++++++++++++++++++++++++++++ | 57% ~01s
|++++++++++++++++++++++++++++++ | 58% ~01s
|++++++++++++++++++++++++++++++ | 59% ~01s
|+++++++++++++++++++++++++++++++ | 61% ~00s
|++++++++++++++++++++++++++++++++ | 62% ~00s
|++++++++++++++++++++++++++++++++ | 63% ~00s
|+++++++++++++++++++++++++++++++++ | 65% ~00s
|+++++++++++++++++++++++++++++++++ | 66% ~00s
|++++++++++++++++++++++++++++++++++ | 67% ~00s
|+++++++++++++++++++++++++++++++++++ | 68% ~00s
|+++++++++++++++++++++++++++++++++++ | 70% ~00s
|++++++++++++++++++++++++++++++++++++ | 71% ~00s
|+++++++++++++++++++++++++++++++++++++ | 72% ~00s
|+++++++++++++++++++++++++++++++++++++ | 73% ~00s
|++++++++++++++++++++++++++++++++++++++ | 75% ~00s
|++++++++++++++++++++++++++++++++++++++ | 76% ~00s
|+++++++++++++++++++++++++++++++++++++++ | 77% ~00s
|++++++++++++++++++++++++++++++++++++++++ | 78% ~00s
|++++++++++++++++++++++++++++++++++++++++ | 80% ~00s
|+++++++++++++++++++++++++++++++++++++++++ | 81% ~00s
|++++++++++++++++++++++++++++++++++++++++++ | 82% ~00s
|++++++++++++++++++++++++++++++++++++++++++ | 84% ~00s
|+++++++++++++++++++++++++++++++++++++++++++ | 85% ~00s
|++++++++++++++++++++++++++++++++++++++++++++ | 86% ~00s
|++++++++++++++++++++++++++++++++++++++++++++ | 87% ~00s
|+++++++++++++++++++++++++++++++++++++++++++++ | 89% ~00s
|+++++++++++++++++++++++++++++++++++++++++++++ | 90% ~00s
|++++++++++++++++++++++++++++++++++++++++++++++ | 91% ~00s
|+++++++++++++++++++++++++++++++++++++++++++++++ | 92% ~00s
|+++++++++++++++++++++++++++++++++++++++++++++++ | 94% ~00s
|++++++++++++++++++++++++++++++++++++++++++++++++ | 95% ~00s
|+++++++++++++++++++++++++++++++++++++++++++++++++ | 96% ~00s
|+++++++++++++++++++++++++++++++++++++++++++++++++ | 97% ~00s
|++++++++++++++++++++++++++++++++++++++++++++++++++| 99% ~00s
|++++++++++++++++++++++++++++++++++++++++++++++++++| 100% elapsed=01s
# Remove mikado genes
markers <- markers[grep("mikado", rownames(markers), invert = TRUE),]
# Get top 30 periportal genes
pp_genes <- rownames(markers[markers$avg_log2FC > 0,])[1:10]
pp_genes
[1] "Saa2;Saa1-1" "HAMP"
[3] "APOA1" "APOC2"
[5] "CRYL1" "AMY1A;AMY1C;AMY1B;AMY2A;AMY2B"
[7] "MT-ATP6" "UROC1"
[9] "APOA2" "MT-CO3"
# Get top 30 pericentral genes
cv_genes <- rownames(markers[markers$avg_log2FC < 0,])[1:10]
cv_genes
[1] "FETUB" "HMGCS1" "CYP2E1" "GLUD1;GLUD2" "CYP1A2" "RGN"
[7] "INMT" "COMT" "FDPS" "SPR-1"
Format for UCell
mySigs <- list()
mySigs$Periportal <- pp_genes
mySigs$Pericentral <- cv_genes
mySigs
$Periportal
[1] "Saa2;Saa1-1" "HAMP"
[3] "APOA1" "APOC2"
[5] "CRYL1" "AMY1A;AMY1C;AMY1B;AMY2A;AMY2B"
[7] "MT-ATP6" "UROC1"
[9] "APOA2" "MT-CO3"
$Pericentral
[1] "FETUB" "HMGCS1" "CYP2E1" "GLUD1;GLUD2" "CYP1A2" "RGN"
[7] "INMT" "COMT" "FDPS" "SPR-1"
Add these as gene signatures
sobj <- AddModuleScore_UCell(sobj, features = mySigs, assay = "SCT")
signature.names <- paste0(names(mySigs), "_UCell")
VlnPlot(sobj, features = signature.names, group.by = "SCT_snn_res.0.2")
SpatialFeaturePlot(sobj,
features = signature.names,
images = 'slice1')
SpatialFeaturePlot(sobj,
features = signature.names,
images = 'slice1.1')
Create figures of spatial plots with signatures
plot1 <- SpatialFeaturePlot(sobj,
features = "Periportal_UCell",
images = 'slice1')
plot2 <- SpatialFeaturePlot(sobj,
features = "Periportal_UCell",
images = 'slice1.1')
pdf("./figures/spatial/periportalSig_spatial_UCell.pdf")
plot1 + plot2
dev.off()
null device
1
plot1 <- SpatialFeaturePlot(sobj,
features = "Pericentral_UCell",
images = 'slice1')
plot2 <- SpatialFeaturePlot(sobj,
features = "Pericentral_UCell",
images = 'slice1.1')
pdf("./figures/spatial/pericentralSig_spatial_UCell.pdf")
plot1 + plot2
dev.off()
null device
1
Create heatmap with signature genes
Correlate UMAP zonation scores with gene expression
FeaturePlot(sobj, features = c("WNT2", "Pericentral_UCell"), blend = TRUE)
Warning: Could not find WNT2 in the default search locations, found in ‘Spatial’ assay instead
FeatureScatter(sobj, feature1 = "WNT2", feature2 = "Pericentral_UCell")
Warning: Could not find WNT2 in the default search locations, found in ‘Spatial’ assay instead
Calculate Z-score for each gene for CV and PP signatures
zscore = (sobj@assays$SCT@scale.data['CYP2E1',] - sobj$Pericentral_UCell)/sd(sobj$Pericentral_UCell)
sobj$cyp2e1_zscore <- scale(zscore)
SpatialFeaturePlot(sobj, features = 'cyp2e1_zscore', images = 'slice1')
Try with RSPO3
zscore = (sobj@assays$SCT@scale.data['RSPO3',] - sobj$Pericentral_UCell)/sd(sobj$Pericentral_UCell)
sobj$rspo3_zscore <- scale(zscore)
SpatialFeaturePlot(sobj, features = 'rspo3_zscore', images = 'slice1')
Correlate all genes with CV and PP signatures
cv_cor <- apply(sobj@assays$SCT@counts, 1, function (x) cor(x, y = sobj$Pericentral_UCell,
method = "spearman"))
Warning: the standard deviation is zero
head(sort(cv_cor, decreasing = TRUE))
FETUB CYP2E1 HMGCS1 CYP1A2 RGN COMT
0.7660823 0.7393928 0.7129019 0.6500996 0.6442300 0.6336671
pp_cor <- apply(sobj@assays$SCT@counts, 1, function (x) cor(x, y = sobj$Periportal_UCell,
method = "spearman"))
Warning: the standard deviation is zero
head(sort(pp_cor, decreasing = TRUE))
HAMP Saa2;Saa1-1 AMY1A;AMY1C;AMY1B;AMY2A;AMY2B
0.7191834 0.6434277 0.5996466
APOA1 CRYL1 APOC2
0.5084247 0.5080673 0.5008200
Write table
spatial_cors <- cbind(cv_cor, pp_cor)
write.table(spatial_cors,
file = "./figures/spatial/spatial_gene_correlations.tsv",
quote = FALSE,
sep = "\t",
row.names = TRUE,
col.names = TRUE)
Save object if needed
saveRDS(sobj,
file = "../spatial/merged_spatial_sobj.RDS")